cmake_minimum_required(VERSION 2.8.5)
include(cmake/Macros.cmake)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    # If this is the root project, issue a project() command so that
    # the Visual Studio generator will create an .sln file.
    set(CMAKE_CONFIGURATION_TYPES "Debug;RelWithAsserts;RelWithDebInfo" CACHE INTERNAL "Build configs")
    project(Turf)
    set_property(GLOBAL PROPERTY USE_FOLDERS ON)
    ApplyTurfBuildSettings()
    set(TURF_WITH_SAMPLES TRUE CACHE BOOL "Include all Turf samples in generated build system")
    set(TURF_MAKE_INSTALLABLE TRUE)
endif()	

# Default values.
# These can be overridden by user, or set to the cache by a parent.
set(TURF_USERCONFIG "" CACHE STRING "Optional path to additional config file (relative to root CMakeLists.txt)")
set(TURF_ENABLE_CPP11 TRUE CACHE BOOL "Enable C++11 compiler support")
set(TURF_PREFER_CPP11 FALSE CACHE BOOL "Prefer C++11 atomics, threads, etc. over native implementations")
set(TURF_WITH_BOOST FALSE CACHE BOOL "Use Boost")
if(TURF_WITH_BOOST)
    set(TURF_PREFER_BOOST FALSE CACHE BOOL "Prefer Boost atomics, threads, etc. over native implementations")
endif()
if(TURF_PREFER_BOOST AND NOT TURF_WITH_BOOST)
    message(FATAL_ERROR "TURF_PREFER_BOOST requires TURF_WITH_BOOST")
endif()
set(TURF_WITH_EXCEPTIONS FALSE CACHE BOOL "Enable compiler support for C++ exceptions")
if(MSVC)
    set(TURF_WITH_SECURE_COMPILER FALSE CACHE BOOL "Enable compiler-generated security checks")
endif()
set(TURF_REPLACE_OPERATOR_NEW TRUE CACHE BOOL "Replace global operator new and delete to use the default Turf heap")
set(TURF_USE_DLMALLOC FALSE CACHE BOOL "Use DLMalloc as the default heap")
if(TURF_USE_DLMALLOC)
    set(TURF_DLMALLOC_DEBUG_CHECKS FALSE CACHE BOOL "Enable debug checks in DLMalloc")
    set(TURF_DLMALLOC_FAST_STATS FALSE CACHE BOOL "Enable fast inUseBytes tracking in DLMalloc")
endif()

# Compile checks.
SimpleCompileCheck(TURF_HAS_STDINT "Checking for <stdint.h>"
    "#include <stdint.h>")
SimpleCompileCheck(TURF_HAS_NOEXCEPT "Checking for noexcept keyword"
    "void foo() noexcept {};")
SimpleCompileCheck(TURF_HAS_CONSTEXPR "Checking for constexpr keyword"
    "static constexpr const char* foo = \"foo\";")
SimpleCompileCheck(TURF_HAS_OVERRIDE "Checking for override keyword"
    "struct Base { virtual void foo() {} };
     struct Derived : Base { virtual void foo() override {} };")
SimpleCompileCheck(TURF_HAS_LONG_LONG "Checking for long long"
    "long long foo;")
SimpleCompileCheck(TURF_HAS_STATIC_ASSERT "Checking for static_assert"
    "static_assert(true);")
SimpleCompileCheck(TURF_HAS_MOVE "Checking for std::move"
    "#include <utility>
     void foo(int& a, int& b) { a = std::move(b); }")

# Initialize variables used to collect include dirs/libraries.
set(TURF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/include")
set(TURF_ALL_INCLUDE_DIRS ${TURF_INCLUDE_DIRS})
set(TURF_ALL_LIBRARIES turf)
set(TURF_ALL_LIBRARY_DIRS "")

# Optional: Locate Boost and append it to the list of include dirs/libraries.
if(TURF_WITH_BOOST)
    add_definitions(-DBOOST_ALL_NO_LIB)
    find_package(Boost REQUIRED system chrono thread atomic)
    list(APPEND TURF_ALL_INCLUDE_DIRS ${Boost_INCLUDE_DIRS})
    list(APPEND TURF_ALL_LIBRARIES ${Boost_LIBRARIES})
    list(APPEND TURF_ALL_LIBRARY_DIRS ${Boost_LIBRARY_DIRS})
    
    MESSAGE( STATUS "Boost_LIBRARIES: " ${Boost_LIBRARIES} )
endif()

# If this is the root listfile, add all samples
if((CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) AND TURF_WITH_SAMPLES)
    file(GLOB children samples/*)
    foreach(child ${children})
        if(EXISTS "${child}/CMakeLists.txt")
            add_subdirectory("${child}")
        endif()
    endforeach()
endif()

# Gather source files.
GetFilesWithSourceGroups(GLOB_RECURSE TURF_FILES ${CMAKE_CURRENT_SOURCE_DIR}/turf turf/*)

# Configure autogenerated headers.
ConfigureFileIfChanged(cmake/turf_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/turf_config.h" TURF_FILES)
if(TURF_USERCONFIG)
    # Interpret TURF_USERCONFIG relative to root project, in case Turf was added as a subdirectory
    GetAbsoluteRelativeTo(absPath "${CMAKE_SOURCE_DIR}" "${TURF_USERCONFIG}")
    ConfigureFileIfChanged("${absPath}" "${CMAKE_CURRENT_BINARY_DIR}/include/turf_userconfig.h" TURF_FILES)
else()
    WriteFileIfDifferent("// TURF_USERCONFIG was left blank. This is a placeholder file.\n" "${CMAKE_CURRENT_BINARY_DIR}/include/turf_userconfig.h" TURF_FILES)
endif()

# Define library target.
add_library(turf ${TURF_FILES})

# Set include dirs for this library (done last).
include_directories(${TURF_ALL_INCLUDE_DIRS})

# Make installable.
if(TURF_MAKE_INSTALLABLE)
    # Allow -DLIB_INSTALL_DIR=<path> to be passed on the command line
    if(NOT DEFINED LIB_INSTALL_DIR)
        set(LIB_INSTALL_DIR lib)
    endif()
    install(TARGETS turf DESTINATION ${LIB_INSTALL_DIR})
    install(DIRECTORY turf/ DESTINATION include/turf FILES_MATCHING PATTERN "*.h" PATTERN "*.inc")
    file(GLOB configHeaders "${CMAKE_CURRENT_BINARY_DIR}/include/*.h")
    install(FILES ${configHeaders} DESTINATION include)
endif()

# Export include dirs/libraries to parent project if we were invoked using add_subdirectory().
if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    set(TURF_INCLUDE_DIRS "${TURF_INCLUDE_DIRS}" PARENT_SCOPE)
    set(TURF_ALL_INCLUDE_DIRS "${TURF_ALL_INCLUDE_DIRS}" PARENT_SCOPE)
    set(TURF_ALL_LIBRARIES "${TURF_ALL_LIBRARIES}" PARENT_SCOPE)
    set(TURF_ALL_LIBRARY_DIRS "${TURF_ALL_LIBRARY_DIRS}" PARENT_SCOPE)
endif()
